﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Security.Permissions;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;

namespace KABS_Commander
{
    public partial class KABS_Commander : Form
    {
        private const int MOUSEEVENTF_LEFTDOWN = 0x02;
        private const int MOUSEEVENTF_LEFTUP = 0x04;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        private const int MOUSEEVENTF_RIGHTUP = 0x10;
        private string configFileName = "command_list.ini";
        private int recvByteNum, sendByteNum;
        private int versionMajor = 1;
        private int versionMinor = 2;
        private int lastLength = 0;

        [DllImport("kernel32")]
        private static extern int WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int WritePrivateProfileSection(string section, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileSection(string section, byte[] retVal, int nSize, string fileName);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileSectionNames(byte[] retVal, int nSize, string fileName);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(uint dwFlags, int dx, int dy, uint cButtons, uint dwExtraInfo);
        

        // Data received
        delegate void AppendTextCallback(string text);
        private void appendText(string text)
        {
            // InvokeRequired required compares the thread ID of the 
            // calling thread to the thread ID of the creating thread. 
            // If these threads are different, it returns true. 
            if (this.richTextBox_interactmsg.InvokeRequired)
            {
                AppendTextCallback d = new AppendTextCallback(appendText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                string data = string.Empty;
                data += text;
                //data = data.Replace('\r', '\n');
                recvByteNum += text.Length;
                toolStripStatusLabel_recv.Text = "Recv " + recvByteNum.ToString();
                toolStripStatusLabel_send.Text = "Send " + sendByteNum.ToString();
                
                data = data.Replace("\r\r\n", System.Environment.NewLine);
                richTextBox_interactmsg.Text += data;
                richTextBox_interactmsg.SelectionStart = richTextBox_interactmsg.Text.Length;
                richTextBox_interactmsg.ScrollToCaret();

            }
        }

        public KABS_Commander()
        {
            InitializeComponent();
            InitializeSerial();
            ResetMsgStatus();
            InitializeVersion();
            InitializeModule();
            InitializeCommand();
            InitializeIPInfo();
            transformToolStripMenuItem_Click(null, null);
        }

        private void DeinitSerial()
        {
            try
            {
                if (serialPort_kabs.IsOpen)
                    serialPort_kabs.Close();
            }
            catch (Exception e)
            {

            }
        }

        //private string getTime()
        //{
        //    return DateAndTime.DateString + " "+ DateAndTime.TimeString +":";
        //}

        //private string getHex(string txt)
        //{
        //    char[] data = txt.ToCharArray();
        //    StringBuilder sb = new StringBuilder();
        //    sb.Append("\n{");

        //    foreach (char c in data)
        //    {
        //        sb.AppendFormat("{0:X2} ", (int)c);
        //    }

        //    sb = sb.Remove(sb.Length - 1, 1);
        //    sb.Append("}\n");
        //    return sb.ToString();
        //}

        private void InitializeVersion()
        {
            this.Text = "KABS_Commander (Version " + versionMajor.ToString() + "." + versionMinor.ToString() + ")";
        }

        // data send 
        // Support enter pressed
        private void sendData(string input)
        {
            if (serialPort_kabs.IsOpen) // use serial
            {
                try
                {
                    serialPort_kabs.Write(input);
                    sendByteNum += input.Length;
                }
                catch (Exception e)
                {
                    serialPort_kabs.Close();
                    setSerialSettingEnable();
                }
                textBox_inputmsg.Text = "";
            }
            else if (socket_comm.Connected)
            {
                byte[] buffer = new byte[128];
                for (int i = 0; i < buffer.Length; i++)
                {
                    buffer[i] = 0;
                    if (i < input.Length)
                        buffer[i] = (byte)input[i];
                }
                try
                {
                    socket_comm.Send(buffer);
                    sendByteNum += input.Length;
                }
                catch (Exception e)
                {
                    socket_comm.Close();
                    button_connectRemote.Text = "Connect";
                    setTCPSettingEnable();
                }
                textBox_inputmsg.Text = "";
            }

            toolStripStatusLabel_send.Text = "Send " + sendByteNum.ToString();
        }

        private void textBox_inputmsg_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                string input = textBox_inputmsg.Text;
                if (checkBox_addenter.Checked) input += "\n";
                if (checkBox_addreturn.Checked) input += "\r";
                sendData(input);
            }
        }

        private void listBox_cmdlist_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ListBox cb = (ListBox)sender;
            string order = cb.SelectedItem.ToString();
            if (checkBox_addenter.Checked) order += "\n";
            if (checkBox_addreturn.Checked) order += "\r";
            sendData(order);
        }

        private void ResetMsgStatus()
        {
            recvByteNum = 0;
            sendByteNum = 0;
            toolStripStatusLabel_recv.Text = recvByteNum.ToString();
            toolStripStatusLabel_send.Text = sendByteNum.ToString();
            richTextBox_interactmsg.Text = "";
            toolStripStatusLabel_recv.Text = "Recv " + recvByteNum.ToString();
            toolStripStatusLabel_send.Text = "Send " + sendByteNum.ToString();
            lastLength = 0;
        }

        private void SetInputEnable()
        {
            bool b = serialPort_kabs.IsOpen || socket_comm.Connected;

            textBox_inputmsg.Enabled = b;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DeinitSerial();
        }

        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ResetMsgStatus();
        }



    }
}
